package com.ypc.webdemo.controller.advice;

import com.ypc.webdemo.controller.dto.ServerCode;
import com.ypc.webdemo.controller.dto.ServerResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.stream.Collectors;

/**
 * @author yinpengcheng
 * @Date 2021/11/11
 */
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ServerResult handler(HttpServletRequest request, Exception e) {
        Throwable t = GlobalExceptionHandler.getThrowable(e);
        if (t instanceof BindException) {
            return ServerResult.result(ServerCode.param_error).setMessage(((BindException) t).getBindingResult().getAllErrors().stream().map(ObjectError::getDefaultMessage).collect(Collectors.joining(";")));
        } else if (t instanceof MethodArgumentNotValidException) {
            return ServerResult.result(ServerCode.param_error).setMessage(((MethodArgumentNotValidException) t).getBindingResult().getAllErrors().stream().map(ObjectError::getDefaultMessage).collect(Collectors.joining(";")));
        }
        log.error(t.getMessage(), t);
        return ServerResult.failure().setMessage(StringUtils.hasLength(t.getMessage()) ? t.getMessage() : "服务内部异常");
    }

    /**
     * 获取底层异常
     *
     * @param e
     * @return
     */
    public static Throwable getThrowable(Throwable e) {
        if (e.getCause() != null) {
            e = GlobalExceptionHandler.getThrowable(e.getCause());
        }
        return e;
    }

}
